﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Commerce.Proxy.TransactionService.v201001;
using CommerceAccountProxy = Microsoft.Commerce.Proxy.AccountService;
using TestWebApplication.CommerceTestDataProvider;
using TestWebApplication.CommerceTransaction;
using System.IO;

namespace TestWebApplication
{
    public class PurchaseHandler
    {

        public static List<PurchaseInfo> purchases = new List<PurchaseInfo>();

        //public static List<PaymentMethod> purchasePms = new List<PaymentMethod>();

        public static PurchaseBundleInput wrapItem(PurchaseContentProductItemInput item)
        {
            PurchaseBundleInput bundle = new PurchaseBundleInput();
            bundle.Title = item.Title;
            bundle.Amount = item.RevenueInfo.RevenueAllocationAmount;
            bundle.Currency = "USD";
            bundle.Description = item.Description;
            bundle.ExternalBundleCatalogId = "1";
            bundle.ExternalBundleId = Guid.NewGuid().ToString();

            bundle.PurchaseProductItemInputSet = new PurchaseProductItemInput[] { item };


            return bundle;
        }

        public static PurchaseInfoInput createPurchaseInfo(PurchaseBundleInput bundle)
        {
            PurchaseInfoInput purchaseInfo = new PurchaseInfoInput();
            purchaseInfo.ExternalPurchaseId = "1";
            purchaseInfo.Title = bundle.Title;

            purchaseInfo.PurchaseBundleInputSet = new PurchaseBundleInput[] { bundle };

            return purchaseInfo;
        }

        public static PurchaseOutput purchase(string piid, string accountID, string surl, string furl, CommerceAccountProxy.Identity requester, PurchaseInfoInput purchaseInfo)
        {
            BillingInfo billingInfo = new BillingInfo();
            billingInfo.BillingMode = BillingMode.ImmediateSettle;
            RegisteredPaymentMethod paymentMethod = new RegisteredPaymentMethod();
            Property successURl = new Property() { Name = "PaymentSuccessUrl", Value = Constants.successUrl };
            Property failureURl = new Property() { Name = "PaymentFailureUrl", Value = Constants.failureUrl };
            paymentMethod.PropertyBag = new Property[] { successURl, failureURl };
            paymentMethod.PaymentMethodID = piid;
            billingInfo.PaymentMethod = new PaymentMethod[] { paymentMethod };
            
            Microsoft.Commerce.Proxy.TransactionService.v201001.CallerInfo callerInfo = CommerceTransactionDataProvider.CreateCallerInfo(requester, accountID);

            Marketplace marketPlace = new Marketplace();
            marketPlace.MarkerplaceGuid = new Guid(Constants.MarketPlaceGuid);
            marketPlace.MarketplaceName = Constants.MarketPlaceName;

            PurchaseContext purchaseContext = new PurchaseContext();
            purchaseContext.ComputeOnly = false;
            purchaseContext.TimeStamp = DateTime.Now;

            CommerceTransactionServiceAdapter transactionAdapter = AdapterFactory.createTransactionServiceAdapter();
            transactionAdapter.Initialize();

            PurchaseOutput purchaseResult = transactionAdapter.Purchase(billingInfo, callerInfo, marketPlace, purchaseContext, purchaseInfo);
            if (purchaseResult.Ack == AckCodeType.Success)
            {
                string purchaseID = purchaseResult.PurchaseInfoOutput.PurchaseId;
                PurchaseInfo info = new PurchaseInfo();
                info.purchaseID = purchaseID;
                info.paymentMothod = paymentMethod;

                purchases.Add(info);
            }

            return purchaseResult;
            
        }

        public static List<GetPurchaseOutput> showPurchases(List<PurchaseInfo> purchases, string accountID, CommerceAccountProxy.Identity requester)
        {
            CommerceTransactionServiceAdapter transactionAdapter = AdapterFactory.createTransactionServiceAdapter();
            transactionAdapter.Initialize();

            List<GetPurchaseOutput> result = new List<GetPurchaseOutput>();
            foreach (PurchaseInfo purchase in purchases)
            {
                DateRange dateRange = new DateRange();
                dateRange.StartDate = DateTime.Now.AddDays(-10);
                dateRange.EndDate = DateTime.Now;


                Microsoft.Commerce.Proxy.TransactionService.v201001.CallerInfo callerInfo = CommerceTransactionDataProvider.CreateCallerInfo(requester, accountID);

                GetPurchaseOutput singleResult = transactionAdapter.GetPurchase(dateRange, callerInfo, purchase.purchaseID);
                result.Add(singleResult);
            }

            return result;

        }

        public static void refundPurchase(string accountID, CommerceAccountProxy.Identity requester, int index, string amount)
        {
            CommerceTransactionServiceAdapter transactionAdapter = AdapterFactory.createTransactionServiceAdapter();
            transactionAdapter.Initialize();

            Microsoft.Commerce.Proxy.TransactionService.v201001.CallerInfo callerInfo = CommerceTransactionDataProvider.CreateCallerInfo(requester, accountID);

            PurchaseInfo purchaseInfo = purchases[index];
            //GetPurchaseOutput purchase = transactionAdapter.GetPurchase(null, callerInfo, purchaseInfo.purchaseID);

            RefundPurchaseOutput refundResult = transactionAdapter.Refund(callerInfo, purchaseInfo.paymentMothod, purchaseInfo.purchaseID, amount);
        }

        public static string purchaseRedirect(PurchaseOutput purchaseResult)
        {
            PurchaseInfoOutput info = purchaseResult.PurchaseInfoOutput;
            if (info.PropertyBag != null)
            {

                foreach (Property property in info.PropertyBag)
                {
                    if (Constants.AsyncPropertyNames.Contains(property.Name))
                    {
                        string html = property.Value;
                        //writeToFile(html);

                        return html;
                    }
                }
            }
            return null;
        }

        public static void writeToFile(string html)
        {
            FileStream newFile = new FileStream(HttpContext.Current.Server.MapPath(Constants.AsyncPurchaseFileLocation), FileMode.Truncate, FileAccess.ReadWrite);
            StreamWriter writer = new StreamWriter(newFile);

            writer.WriteLine(html);

            writer.Flush();
        }


    }
}